#    Copyright 2008, 2009 Tri-County Electric Cooperative, St. Matthews, South Carolina
#    This file is part of COOPIP.
#    COOPIP is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#    COOPIP is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#    You should have received a copy of the GNU General Public License
#    along with COOPIP.  If not, see <http://www.gnu.org/licenses/>.

import os
import datetime
import shutil

#************************BEGIN Add Include Files to Path************************
import sys
NeededPaths=['/opt/coopip/djangoproject/include', '/opt/coopip/djangoproject']
for path in NeededPaths:
    if(not path in sys.path):
        sys.path.append(path)
#************************END   Add Include Files to Path************************
from django.contrib.gis.geos import *
import os, time, psycopg2, datetime
#********************Setup psycopg2 and django section********************
PathDjangoRoot="/opt/coopip/"
if(not PathDjangoRoot in sys.path):
    sys.path.append(PathDjangoRoot)
from django.core.management import setup_environ
import djangoproject
from djangoproject import settings
setup_environ(settings)
from models import *
#********************Setup psycopg2 and django section********************

from django.template import Context, loader
from django.http import HttpResponse
from django import forms
import os
import datetime
import djangoproject.settings
import COOPIP_Misc
import djangoproject.models.ipbase
import COOPIP_FormGeneral, COOPIP_FormRevenueProtection, COOPIP_FormIntranet, COOPIP_FormNetworkDevice
import COOPIP_FormCISReport, COOPIP_FormGISReport, COOPIP_FormCOOPTalk, COOPIP_FormAMRReport, COOPIP_FormMeterPing, COOPIP_FormDispatch


def BuildAndProcessMeterForm(request, FailedMeters, ActiveButNotAuthorizedMeters, NotFoundMeters, ServiceOrderMeters, InvestigationMeters): 
    ProcessMeterFormRequest(request) #need to process directly from request, then get lists of meters, but do that after getting basics working
    FormDictionary=BuildMeterForm(FailedMeters, ActiveButNotAuthorizedMeters, NotFoundMeters, ServiceOrderMeters, InvestigationMeters)
    if request.method == 'POST':  #Setup the form so it can be processed/modified on this postback
        form=COOPIP_Misc.DynForm()
        form.setFields(FormDictionary)
        form.setData(request.POST)
        data={}
        for i in form.data.keys():  #Copy the Form Data to a dictionary then back to the form so it can be modified for the next screen view
            data[i] = form.data[i]
        form.data = data
    else:   #Otherwise, setup the Boolean values checked for processing to false
        form=COOPIP_Misc.DynForm()
        form.setFields(FormDictionary)
        form.data={}
    return form


def FormGetBoolean(form, FieldName):
    try:
        Result=bool(form.data[FieldName] == 'on')
    except:
        Result=False
    return Result

def FormGetFloat(form, FieldName, Default=0):
    try:
        String=form.data[FieldName]
    except:
        return Default
    String = String.replace(',', '')
    try:
        Result=float(String)
    except:
        Result=Default
    return Result

def FormGetInteger(form, FieldName, Default=0):
    try:
        return int(FormGetFloat(form, FieldName, Default))
    except:
        return Default

def FormGetString(form, FieldName, Default=''):
    try:
        Result=form.data[FieldName]
    except:
        Result=Default
    return Result



def StringToDate(DateString):
    """Attempts To Convert:
    'YYYY-MM-DD' to a Date 
    'MM/DD/YYYY', 'MM/YYYY', or 'YYYY' to a Date"""
    if(not DateString):
        return None
    if(DateString.find('-') <> -1):
        Split=DateString.split('-')
        Year=int(Split[0])
        Month=int(Split[1])
        Day=int(Split[2][:2])
    elif(DateString.find('/') <> -1):        
        Split=DateString.split('/')
        if(len(Split) == 3):
            Year=int(Split[2])
            Month=int(Split[0])
            Day=int(Split[1])
        elif(len(Split) == 2):
            Year=int(Split[1])
            Month=int(Split[0])
            Day=1
        else:
            Year=int(Split[0])
            Month=1
            Day=1
    else:
        Year=int(DateString)
        Month=1
        Day=1
    return datetime.date(Year, Month, Day)

def StringDateTimeToDateTime(DateTimeString):
    """Attempts To Convert:
    'YYYY-MM-DD HH-MM-SS.SSS...' to a DateTime,
    returns None if it fails,
    for example: 
               '2008-09-26 15:05:43.222615'
    to:  datetime.datetime(2008, 9, 26, 15, 5, 43, 222615)"""
    if(not DateTimeString):
        return None
    try:
        Year=int(DateTimeString[:4])
        Month=int(DateTimeString[5:7])
        Day=int(DateTimeString[8:10])
        Hour=int(DateTimeString[11:13])
        Minute=int(DateTimeString[14:16])
        Second=int(DateTimeString[17:19])  
        PartialSeconds=int(DateTimeString[20:])
        return datetime.datetime(Year, Month, Day, Hour, Minute, Second, PartialSeconds)
    except:
        return StringToDate(DateTimeString)

def String_MM_DD_YYYY_HH_MM__Or_HH_MM_ToDateTime(DateTimeString):
    """Attempts to Convert:  
    'MM-DD-YYYY HH-MM' to a datetime
    Otherwise, converts a:
    'HH-MM' to a datetime, with a date of today
    """

    if(not DateTimeString):
        return None
    DateTimeString=DateTimeString.lower()
    if('p' in DateTimeString):
        PMIndicator=True
    else:
        PMIndicator=False
    FilteredStringList=[]
    for i in DateTimeString:
        if(i in '0123456789'):
            FilteredStringList.append(i)
        else:
            FilteredStringList.append(' ')
    SplitString=''.join(FilteredStringList).split(' ')
    NoEmptyElements=[]
    for i in SplitString:
        if(i):
            NoEmptyElements.append(i)
    if(not len(NoEmptyElements) in [2, 5]):
        return None
    if(len(NoEmptyElements) == 2):
        Hour = int(NoEmptyElements[0])
        if(PMIndicator):
            Hour=Hour + 12
        Minute=int(NoEmptyElements[1])
        Year=datetime.datetime.now().year
        Month=datetime.datetime.now().month
        Day=datetime.datetime.now().day
    else:
        Month=int(NoEmptyElements[0])
        Day=int(NoEmptyElements[1])
        Year=int(NoEmptyElements[2])
        Hour=int(NoEmptyElements[3])
        if(PMIndicator):
            Hour = Hour + 12
        Minute=int(NoEmptyElements[4])
    return datetime.datetime(Year, Month, Day, Hour, Minute)


def FormGetDateTime(form, FieldName):
    String=FormGetString(form, FieldName)
    try:
        DateTime=StringDateTimeToDateTime(String)
    except:
        return None
    return DateTime


def FormGetDateTime2(form, FieldName):
    String=FormGetString(form, FieldName)
    try:
        DateTime=String_MM_DD_YYYY_HH_MM__Or_HH_MM_ToDateTime(String)
    except:
        return None
    return DateTime


def FormGetGeographicData(form, FieldName):
    try:
        return fromstr(form.data[FieldName])
    except:
        return None

def FormGetObjectFromid(form, FieldName, Object):
    Objectid=FormGetInteger(form, FieldName)
    if(id):
        Result=Object.objects.all().filter(id=Objectid)
    else:
        return None
    if(Result):
        return Result[0]
    else:
        return None


def GetNumberOfMetersListedOnForm(FailedMeters, ActiveButNotAuthorizedMeters, NotFoundMeters, ServiceOrderMeters, InvestigationMeters):
    return len(FailedMeters) + len(ActiveButNotAuthorizedMeters) + len(NotFoundMeters) + len(ServiceOrderMeters) + len(InvestigationMeters)

def BuildMeterForm(FailedMeters, ActiveButNotAuthorizedMeters, NotFoundMeters, ServiceOrderMeters, InvestigationMeters):
    NumberOfMetersListedOnForm=GetNumberOfMetersListedOnForm(FailedMeters, ActiveButNotAuthorizedMeters, NotFoundMeters, ServiceOrderMeters, InvestigationMeters)
    Dict={}
    Dict['PingMeterCommand'] = forms.CharField(required=False, widget=forms.TextInput(attrs={'size':'12'}))
    for i in range(0, NumberOfMetersListedOnForm):
        Dict['UpdateIndicator' + str(i)]=forms.BooleanField(required=False)
        Dict['MeterNumber' + str(i)]=forms.CharField(required=False, widget=forms.TextInput(attrs={'size':'7', 'READONLY':'True'}))
        Dict['LastSuccessfulPingDateTime' + str(i)]=forms.CharField(required=False, widget=forms.TextInput(attrs={'size':'10', 'READONLY':'True'}))
        Dict['TagNumber' + str(i)]=forms.CharField(required=False, widget=forms.TextInput(attrs={'size':'4', 'READONLY':'True'}))
        Dict['LastPingResponseDateTime' + str(i)]=forms.CharField(required=False, widget=forms.TextInput(attrs={'size':'10', 'READONLY':'True'}))
        Dict['AppearedOnNotVerifiedListDateTime' + str(i)]=forms.CharField(required=False, widget=forms.TextInput(attrs={'size':'10', 'READONLY':'True'}))
        Dict['InvestigationIndicator' + str(i)]=forms.BooleanField()
        Dict['Description' + str(i)]=forms.CharField(required=False, widget=forms.Textarea(attrs={'rows':'2', 'cols':'50'}))
        Dict['InvestigationStartDateTime' + str(i)]=forms.CharField(required=False, widget=forms.TextInput(attrs={'size':'10', 'READONLY':'True'}))
        Dict['GISCircuitNumber' + str(i)]=forms.CharField(required=False, widget=forms.TextInput(attrs={'size':'2', 'READONLY':'True'}))
        Dict['ServiceOrderDescription' + str(i)]=forms.CharField(required=False, widget=forms.Textarea(attrs={'rows':'2', 'cols': '20', 'READONLY':'True'}))
    return Dict

def ProcessMeterFormRequest(request):
    #raise(Exception(str(request.POST['PingMeterCommand'])))
    Dict=request.POST
    try:
        PingMeterCommand=request.POST['PingMeterCommand']
        PingMeterCommandInteger=int(request.POST['PingMeterCommand'])
    except:
        PingMeterCommand=''
        PingMeterCommandInteger=0
    #raise(Exception(dir(djangoproject.models.)))
    if(PingMeterCommand):
        Meters=[]
        if(djangoproject.models.ipbase.Meter.objects.filter(GISCircuitNumber=PingMeterCommand)):
            Meters=djangoproject.models.ipbase.Meter.objects.filter(GISCircuitNumber=PingMeterCommand)
        elif(djangoproject.models.ipbase.Meter.objects.filter(SerialNumber=PingMeterCommand)):
            TempMeter=djangoproject.models.ipbase.Meter.objects.filter(SerialNumber=PingMeterCommand)[0]
            Meters=[]
            Meters.append(TempMeter)
            NearbyMeters=TempMeter.GetNearbyMeters()
            for i in NearbyMeters:
                Meters.append(i)
        elif(PingMeterCommandInteger and (PingMeterCommandInteger % 100 == 0)): 
            Meters = []
            TempMeters=djangoproject.models.ipbase.Meter.objects.all()
            #Need to add code to get all matching substation meters here.
        for meter in Meters:
            meter.Ping()
    i = 0
    while(True):
        if(not request.POST.has_key('Description' + str(i))):
            break
        if(request.POST.has_key('UpdateIndicator' + str(i))):
            UpdateIndicator= (request.POST['UpdateIndicator' + str(i)] == 'on')
        else:
            UpdateIndicator=False
        if(UpdateIndicator):
            MeterNumber = (request.POST['MeterNumber' + str(i)])
            if(request.POST.has_key('InvestigationIndicator' + str(i))):
                InvestigationIndicator= (request.POST['InvestigationIndicator' + str(i)] == 'on')
            else:
                InvestigationIndicator=False
            Description = (request.POST['Description' + str(i)])
            meter=djangoproject.models.ipbase.Meter.objects.filter(SerialNumber=MeterNumber)[0]
            meter.InvestigationIndicator=InvestigationIndicator
            meter.Description=Description
            meter.CalculateSymbology(False)
            meter.save()
        i = i + 1


def PopulateMeterForm(form, FailedMeters, ActiveButNotAuthorizedMeters, NotFoundMeters, ServiceOrderMeters, InvestigationMeters):
    NumberOfMetersListedOnForm=GetNumberOfMetersListedOnForm(FailedMeters, ActiveButNotAuthorizedMeters, NotFoundMeters, ServiceOrderMeters, InvestigationMeters)
    Total = 0
    for i in range(0, len(FailedMeters)):
        form.data['UpdateIndicator' + str(Total)]=False
        form.data['MeterNumber' + str(Total)]=FailedMeters[i].SerialNumber
        form.data['LastSuccessfulPingDateTime' + str(Total)]=FailedMeters[i].LastSuccessfulPingDateTime
        form.data['TagNumber' + str(Total)]=FailedMeters[i].TagNumber
        form.data['LastPingResponseDateTime' + str(Total)]=FailedMeters[i].LastPingResponseDateTime
        form.data['AppearedOnNotVerifiedListDateTime' + str(Total)]=FailedMeters[i].AppearedOnNotVerifiedListDateTime
        form.data['InvestigationIndicator' + str(Total)]=FailedMeters[i].InvestigationIndicator
        form.data['Description' + str(Total)]=FailedMeters[i].Description
        form.data['InvestigationStartDateTime' + str(Total)]=FailedMeters[i].InvestigationStartDateTime
        form.data['GISCircuitNumber' + str(Total)]=FailedMeters[i].GISCircuitNumber
        Total=Total + 1
    for i in range(0, len(ActiveButNotAuthorizedMeters)):
        form.data['UpdateIndicator' + str(Total)]=False
        form.data['MeterNumber' + str(Total)]=ActiveButNotAuthorizedMeters[i].SerialNumber
        form.data['LastSuccessfulPingDateTime' + str(Total)]=ActiveButNotAuthorizedMeters[i].LastSuccessfulPingDateTime
        form.data['TagNumber' + str(Total)]=ActiveButNotAuthorizedMeters[i].TagNumber
        form.data['LastPingResponseDateTime' + str(Total)]=ActiveButNotAuthorizedMeters[i].LastPingResponseDateTime
        form.data['AppearedOnNotVerifiedListDateTime' + str(Total)]=ActiveButNotAuthorizedMeters[i].AppearedOnNotVerifiedListDateTime
        form.data['InvestigationIndicator' + str(Total)]=ActiveButNotAuthorizedMeters[i].InvestigationIndicator
        form.data['Description' + str(Total)]=ActiveButNotAuthorizedMeters[i].Description
        form.data['InvestigationStartDateTime' + str(Total)]=ActiveButNotAuthorizedMeters[i].InvestigationStartDateTime
        form.data['GISCircuitNumber' + str(Total)]=ActiveButNotAuthorizedMeters[i].GISCircuitNumber
        Total=Total + 1
    for i in range(0, len(NotFoundMeters)):
        form.data['UpdateIndicator' + str(Total)]=False
        form.data['MeterNumber' + str(Total)]=NotFoundMeters[i].SerialNumber
        form.data['LastSuccessfulPingDateTime' + str(Total)]=NotFoundMeters[i].LastSuccessfulPingDateTime
        form.data['TagNumber' + str(Total)]=NotFoundMeters[i].TagNumber
        form.data['LastPingResponseDateTime' + str(Total)]=NotFoundMeters[i].LastPingResponseDateTime
        form.data['AppearedOnNotVerifiedListDateTime' + str(Total)]=NotFoundMeters[i].AppearedOnNotVerifiedListDateTime
        form.data['InvestigationIndicator' + str(Total)]=NotFoundMeters[i].InvestigationIndicator
        form.data['Description' + str(Total)]=NotFoundMeters[i].Description
        form.data['InvestigationStartDateTime' + str(Total)]=NotFoundMeters[i].InvestigationStartDateTime
        form.data['GISCircuitNumber' + str(Total)]=NotFoundMeters[i].GISCircuitNumber
        Total=Total + 1
    for i in range(0, len(ServiceOrderMeters)):
        form.data['UpdateIndicator' + str(Total)]=False
        form.data['MeterNumber' + str(Total)]=ServiceOrderMeters[i].SerialNumber
        form.data['LastSuccessfulPingDateTime' + str(Total)]=ServiceOrderMeters[i].LastSuccessfulPingDateTime
        form.data['TagNumber' + str(Total)]=ServiceOrderMeters[i].TagNumber
        form.data['LastPingResponseDateTime' + str(Total)]=ServiceOrderMeters[i].LastPingResponseDateTime
        form.data['AppearedOnNotVerifiedListDateTime' + str(Total)]=ServiceOrderMeters[i].AppearedOnNotVerifiedListDateTime
        form.data['InvestigationIndicator' + str(Total)]=ServiceOrderMeters[i].InvestigationIndicator
        form.data['Description' + str(Total)]=ServiceOrderMeters[i].Description
        form.data['InvestigationStartDateTime' + str(Total)]=ServiceOrderMeters[i].InvestigationStartDateTime
        form.data['GISCircuitNumber' + str(Total)]=ServiceOrderMeters[i].GISCircuitNumber
        form.data['ServiceOrderDescription' + str(Total)]=ServiceOrderMeters[i].ServiceOrderDescription
        Total=Total + 1
    for i in range(0, len(InvestigationMeters)):
        form.data['UpdateIndicator' + str(Total)]=False
        form.data['MeterNumber' + str(Total)]=InvestigationMeters[i].SerialNumber
        form.data['LastSuccessfulPingDateTime' + str(Total)]=InvestigationMeters[i].LastSuccessfulPingDateTime
        form.data['TagNumber' + str(Total)]=InvestigationMeters[i].TagNumber
        form.data['LastPingResponseDateTime' + str(Total)]=InvestigationMeters[i].LastPingResponseDateTime
        form.data['AppearedOnNotVerifiedListDateTime' + str(Total)]=InvestigationMeters[i].AppearedOnNotVerifiedListDateTime
        form.data['InvestigationIndicator' + str(Total)]=InvestigationMeters[i].InvestigationIndicator
        form.data['Description' + str(Total)]=InvestigationMeters[i].Description
        form.data['InvestigationStartDateTime' + str(Total)]=InvestigationMeters[i].InvestigationStartDateTime
        form.data['GISCircuitNumber' + str(Total)]=InvestigationMeters[i].GISCircuitNumber
        Total=Total + 1
    return form

class LoginForm(forms.Form):
    Username=forms.CharField(widget=forms.TextInput(attrs={'size':'5.5'}))
    Password=forms.CharField(widget=forms.PasswordInput(attrs={'size':'5.5'}))


def BuildDynamicForm(request, FormName, SpecialBuildFormDataDict={}):
    if(FormName=='AddressPhone'):
        FormDictionary=COOPIP_FormGeneral.BuildAddressPhoneForm(SpecialBuildFormDataDict)
    elif(FormName=='RevenueProtectionIncident'):
        FormDictionary=COOPIP_FormRevenueProtection.BuildIncidentForm(SpecialBuildFormDataDict)
    elif(FormName=='RevenueProtectionMeterInvestigation'):
        FormDictionary=COOPIP_FormRevenueProtection.BuildMeterInvestigationForm(SpecialBuildFormDataDict)
    elif(FormName=='RevenueProtectionReport'):
        FormDictionary=COOPIP_FormRevenueProtection.BuildRevenueProtectionReportForm(SpecialBuildFormDataDict)
    elif(FormName=='RevenueProtectionReportNote'):
        FormDictionary=COOPIP_FormRevenueProtection.BuildRevenueProtectionReportNoteForm(SpecialBuildFormDataDict)
    elif(FormName=='IntranetMessage'):
        FormDictionary=COOPIP_FormIntranet.BuildMessageForm(SpecialBuildFormDataDict)
    elif(FormName=='IntranetDispatchBoard'):
        FormDictionary=COOPIP_FormIntranet.BuildDispatchBoardForm(SpecialBuildFormDataDict)
    elif(FormName=='MeterPingReport'):
        FormDictionary=COOPIP_FormIntranet.BuildMeterPingReportForm(SpecialBuildFormDataDict)
    elif(FormName=='SearchInMeters'):
        FormDictionary=COOPIP_FormRevenueProtection.BuildSearchInMetersForm(SpecialBuildFormDataDict)
    elif(FormName=='NetworkDeviceAddEdit'):
        FormDictionary=COOPIP_FormNetworkDevice.BuildNetworkDeviceAddEditForm(SpecialBuildFormDataDict)
    elif(FormName=='TruckMovement'):
        FormDictionary=COOPIP_FormRevenueProtection.BuildTruckMovementForm()
    elif(FormName=='DeleteFromAMR'):
        FormDictionary=COOPIP_FormRevenueProtection.BuildDeleteFromAMRForm()
    elif(FormName=='SSNSearch'):
        FormDictionary=COOPIP_FormCISReport.BuildSSNSearchForm()
    elif(FormName=='CISReportBarcode'):
        FormDictionary=COOPIP_FormCISReport.BuildCISReportBarcodeForm()    
    elif(FormName=='DispatchAlarm'):
        FormDictionary=COOPIP_FormDispatch.BuildAlarmForm(SpecialBuildFormDataDict)
    elif(FormName=='DispatchAlarmContacts'):
        FormDictionary=COOPIP_FormDispatch.BuildAlarmContactForm(SpecialBuildFormDataDict)
    elif(FormName=='DispatchBoard'):
        FormDictionary=COOPIP_FormDispatch.BuildMessageBoardForm(SpecialBuildFormDataDict)
    elif(FormName=='DispatchCrewLog'):
        FormDictionary=COOPIP_FormDispatch.BuildCrewLogForm(SpecialBuildFormDataDict)
    elif(FormName=='DispatchOutageAssignment'):
        FormDictionary=COOPIP_FormDispatch.BuildOutageAssignmentForm(SpecialBuildFormDataDict)
    elif(FormName=='DispatchVehicles'):
        FormDictionary=COOPIP_FormDispatch.BuildVehicleForm(SpecialBuildFormDataDict)
    elif(FormName=='DispatchDynamicCircuitAssignments'):
        FormDictionary=COOPIP_FormDispatch.BuildDynamicCircuitAssignmentForm()
    elif(FormName=='TransformerUsageAnalysis'):
        FormDictionary=COOPIP_FormGISReport.BuildTransformerUsageAnalysisForm()
    elif(FormName=='COOPTalkTestHarness'):
        FormDictionary=COOPIP_FormCOOPTalk.BuildTestHarnessForm()
    elif(FormName=='OutdoorLightingBillingPhaseTable'):
        FormDictionary=COOPIP_FormCISReport.BuildOutdoorLightingBillingPhaseTableForm(SpecialBuildFormDataDict)
    elif(FormName=='RecentMeterReads'):
        FormDictionary=COOPIP_FormAMRReport.BuildRecentMeterReadsForm()
    elif(FormName=='MeterPingConfiguration'):
        FormDictionary=COOPIP_FormMeterPing.BuildMeterPingConfigurationForm(SpecialBuildFormDataDict)
    elif(FormName=='ViewVehicleHistory'):
        FormDictionary=COOPIP_FormRevenueProtection.BuildVehicleHistoryForm()
    else:
        raise(Exception('An Invalid Form Name was specified in BuildForm in COOPIP_Form.py'))
    if request.method == 'POST':  #Setup the form so that it can be processed/modified on this postback
        form=COOPIP_Misc.DynForm()
        form.setFields(FormDictionary)
        form.setData(request.POST)
        data={}
        for i in form.data.keys():     #Copy the Form Data to a dictionary then back to the form so that it can be modified for the next screen view
            data[i] = form.data[i]
        form.data = data
    else:  #Otherwise, setup the Boolean Values checked for processing to false
        form=COOPIP_Misc.DynForm()
        form.setFields(FormDictionary)
        form.data={}
    return form


